摸着良心说,你了解HTTPS工作原理吗?
当你打开浏览器,访问某个网站,如果网址旁有个小锁,代表访问的网址是安全的,反之不安全。
为什么需要 HTTPS?
我们为什么需要 HTTPS?主要有如下三个原因:
HTTPS 是什么?SSL/TLS 是什么?
于是 IETF 将 SSL 作了标准化,重新命名为 TLS(Transport Layer Security)。在 1999 年,TLS 1.0 诞生了(其实也就是 SSL 3.1)。
SSL/TLS 发展史
SSL/TLS 发展史如上图:
Google 将在 Chrome 72 中不推荐使用 TLS 1.0 和 1.1,而 Chrome 81 之后将会完全不支持。
Mozilla 的 Firefox,微软的 Edge 和 IE 以及苹果的 Safari 都会分别于 2020 年逐渐移除对 TLS 1.0 和 1.1 的支持。
要关闭浏览器对 TLS 1.0 和 1.1 的支持,可以在 Internet 选项中修改:
SSL/TLS 的工作原理
需要理解 SSL/TLS 的工作原理,我们需要掌握加密算法。
加密算法有两种:
对称加密
非对称加密
先来看下整个 SSL/TLS 的握手过程,之后我们再分步骤详细解读,每一步都干了些什么。
①当 TCP 建立连接之后,TLS 握手的第一步由客户端发起,发送 ClientHello 的消息到服务器。
客户端支持的 SSL/TLS 版本
客户端支持的加密套件(Cipher Suites)
会话 Idsession id(如果有的值的话,服务器端会复用对应的握手信息,避免短时间内重复握手)
随机数 client-random
延伸阅读:
加密套件名如:“TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA256”,这么长的名字看着有点晕吧,不用怕,其实它的命名非常规范,格式很固定。基本的形式是“密钥交换算法-服务身份验证算法-对称加密算法-握手校验算法”。
握手过程中,证书签名使用的 RSA 算法,如果证书验证正确,再使用 ECDHE 算法进行密钥交换,握手后的通信使用的是 AES256 的对称算法分组模式是 GCM。
验证证书签名合法性使用 SHA256 作哈希算法检验。相关的算法的用处将在后文中详解。
②然后服务器端在收到这个 ClientHello,从中选择服务器支持的版本和套件,发送 ServerHello 消息:
服务器所能支持的最高 SSL/TLS 版本
服务器选择的加密套件
随机数 server-random
会话 Idsession id(用于下次复用当前握手的信息,避免短时间内重复握手。)
随后服务器发送服务器的安全证书(含公钥)。如果需要客户端也提供证书的话,还会发出客户端证书请求(Client Certificate Request),只有少数金融机构才需要客户端也提供客户端证书。
此后客户端发送 Server Hello Done 消息表示 Hello 阶段完成。
③客户端收到 ServerHello 后,会对收到的证书进行验证。
我们来看一下为什么可以通过 CA(Certificate Authority,证书颁发机构)签发的证书来确认网站的身份?
当我们安装操作系统或者浏览器的时候,会安装一组可信任的 CA(根证书 CA 包括 GlobalSign、GeoTrust、Verisign 等)列表。
根 CA 如 GlobalSign 就在我们的可信任的 CA 列表里,你的浏览器或者操作系统含有 GlobalSign 的公钥。
浏览器首先用哈希函数对明文信息的摘要做哈希得到一个哈希值(用到的就是证书中的签名哈希算法 SHA256),然后用根 CA 的公钥对根证书的签名作解密得到另一个哈希值(用到的算法就是 RSA 非对称算法)。
这样就免受中间人攻击了,因为假如有中间人修改了证书的内容(如将证书中的公钥替换成自己的公钥),那么将获得不同的哈希值,从而两个哈希值不匹配导致验证失败。
如果要绕过这个机制,中间人必须要也替换签名,使签名也相匹配。而做到这一点就需要破解到了根证书的密钥(而这是不可能的,中间人必然会失败)。
那聪明的你肯定也想到了,如果你开发了一个系统还在测试阶段,还没有正式申请一张证书,那么你可以为服务器自签名一张证书,然后将证书导入客户端的 CA 信任列表中。
可以看到证书路径是:
GlobalSign Root CA-R2→GTS CA 1O1→*.google.com
因为我们的浏览器信任 GlobalSign Root CA,根据信任链机制,你相信了根 CA 颁发的证书,也要相信它签名的子 CA 颁发的证书,也要相信子 CA 签名的子子 CA 的证书。
而我们通过一级级的校验,如果从根证书到最下层的证书都没有被篡改过,我们就相信最下层的这个服务器证书是合法的。所以在这个机制中,你就需要无条件的相信根证书的颁发机构。
如果通过验证,客户端生成一个随机数 pre-master,用于密钥交换过程。
④密钥交换过程:客户端用第三步中服务器的证书中拿到服务器的公钥,用这个公钥加密(算法是加密套件中的密钥交换算法,譬如 ECDHE 算法)生成密文发送给服务器。
⑤客户端用 server-random+client-random+pre-master 一起计算出对称密钥 master secret。
⑥服务器收到第四步的信息之后,用服务器的私钥对密文进行解密得到密钥 pre-master。
因为只有服务器有私钥,可以针对客户端发出的加密过的信息进行解密得到 pre-master,这样就保证了只有服务器和客户端知道 pre-master。
服务器端也可以用 server-random+client-random+pre-master 一起计算出对称密钥 master secret。
现在客户端和服务器均有密钥 master secret 了,后面就可以用它来进行加密和解密了。
为什么不能只用一个 pre-master 作为之后加密的对称密钥?
⑦客户端用 master secret 加密了一条握手完成的消息发送给服务器。
⑧服务器端也回发了一条用 master secret 加密的握手完成的消息。
⑨当两方都收到对方发送的握手消息之后,也成功解密后,就可以用 master secret 愉快的开始数据加密和解密了。
综上,整个握手过程主要是通过一系列步骤通过非对称加密的算法交换得到了 master secret,这个步骤通常需要几百毫秒,但是就是这一顿猛操作之后使得只有服务器和客户端知道 master secret。
之后的通信又利用了高效的对称算法对所有信息进行加密和解密,虽然加密和解密也需要耗时耗流量,不过信息是完全不可能被别人篡改和破解的,这一点损耗还是值得的。
作者:Stephanie Tang
编辑:陶家龙
出处:stephanietang.github.io/2020/04/19/how-https-works/
后台回复“加群”,带你进入高手如云交流群
推荐阅读:
晋升、面试中绕不开的性能优化问题
史上最全Linux面试题(2020最新版)
喜欢,就给我一个“在看”
10T 技术资源大放送!包括但不限于:云计算、虚拟化、微服务、大数据、网络、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公众号内回复「1024」,即可免费获取!!